package org.testfire.realm.control.testfire;

import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.transaction.UserTransaction;
import org.apache.log4j.Logger;
import org.testfire.realm.control.user.UserBean;
import org.testfire.realm.model.entities.testfire.TestEntity;
import org.testfire.realm.model.entities.testfire.TestsetEntity;
import org.testfire.realm.model.entities.testfire.TestsetResultEntity;
import org.testfire.realm.util.MapStoreBean;

/**
 * Created by IntelliJ IDEA.
 * User: granum
 * Date: Aug 22, 2007
 * Time: 2:06:59 PM
 * <p/>
 * Request managed bean.
 */
public class TestsetBean
{
    // Inject the lgsrealm entity manager, as defined in the persistence.xml file.
    @PersistenceContext(unitName = "testfire")
    EntityManager em;

    @Resource
    private UserTransaction utx;

    /* @Managed */
    private TestFireDBAO testfireDBAO;

    private UserBean userBean;

    private MapStoreBean mapStoreBean;

    List<TestsetEntity> testsets = null;

    TestsetEntity testset = null;

    List<TestEntity> tests;

    List<TestsetResultEntity> testsetResults;

    Logger log = Logger.getLogger( TestsetBean.class );

    /**
     * Get a testset by id
     * @param id The id.
     * @return
     */
    public TestsetEntity getTestset( Integer id )
    {
        if ( testset == null )
        {
            try
            {
                testset = em.find( TestsetEntity.class, id ) ;
            }
            catch ( Exception e )
            {
                log.error( "Could not find / refresh testset object.", e );
            }
        }
        return testset;
    }

    /**
     * Get all testsets.
     * @return All testsets.
     */
    public List<TestsetEntity> getTestsets()
    {
        if ( testsets == null )
        {
            try
            {
                Query query = em.createQuery( "SELECT OBJECT(ts) FROM TestsetEntity ts " );
                this.testsets = query.getResultList();
            }
            catch ( Exception e )
            {
                log.error( "Could not load testsets.", e );
            }
        }
        return testsets;
    }

    /**
     * Get all tests.
     * @return All tests.
     */
    public List<TestEntity> getTests()
    {
        if ( this.tests == null )
        {
            Integer id = (Integer)mapStoreBean.get( "testsetId" );
            if ( id != null )
            {
                this.tests = getTestset( id ).getTests();
            }
            else
            {
                /* @todo throw an error that will propogate back to the user. */
            }
        }
        return this.tests;
    }

    /**
     * Get only a test that is named <code>name</code> and is a memeber of a particular testset.
     * This method checks for existence before running the query, and therefor will not cause the transaction
     * to be flagged for rollback if the record does not exist.
     * @param testsetId The id of the testset of interest.
     * @param testName The name of the Test of interest.
     * @return The test, if found, or null.
     */
    public TestEntity getTest( Integer testsetId, String testName )
    {
        TestEntity test = null;
        try
        {
            Query query = em.createQuery(
                "SELECT count(t) FROM TestEntity t, TestsetEntity ts WHERE ts.id = :testsetId AND t.name = :testName AND t member of ts.tests" );
            query.setParameter( "testsetId", testsetId );
            query.setParameter( "testName", testName );
            Long count = (Long)query.getSingleResult();
            if(count > 0)
            {
                query = em.createQuery(
                    "SELECT OBJECT(t) FROM TestEntity t, TestsetEntity ts WHERE ts.id = :testsetId AND t.name = :testName AND t member of ts.tests" );
                query.setParameter( "testsetId", testsetId );
                query.setParameter( "testName", testName );

                test = (TestEntity)query.getSingleResult();
            }

        }
        catch ( Exception e )
        {
            log.error( "Could not load testsets.", e );
        }
        return test;
    }


    

    public List<TestsetResultEntity> getResults()
    {
        if ( this.testsetResults == null )
        {
            Integer id = (Integer)mapStoreBean.get( "testsetId" );
            if ( id != null )
            {
                this.testsetResults = getTestset( id ).getResults();
            }
            else
            {
                /* @todo throw an error that will propogate back to the user. */
            }
        }
        return this.testsetResults;
    }

    public TestFireDBAO getTestfireDBAO()
    {
        return testfireDBAO;
    }

    public void setTestfireDBAO( TestFireDBAO testfireDBAO )
    {
        this.testfireDBAO = testfireDBAO;
    }

    public UserBean getUserBean()
    {
        return userBean;
    }

    public void setUserBean( UserBean userBean )
    {
        this.userBean = userBean;
    }

    public void setMapStoreBean( MapStoreBean mapStoreBean )
    {
        this.mapStoreBean = mapStoreBean;
    }
}